﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace Mari.SmartHotel.Controls
{
    public static class ShellPanesService
    {
        private static object lastMessage = null;
        private static object currentMessage = null;

        public static ContentControl HelpPaneContentControl { get; set; }
        public static ContentControl TaskPaneContentControl { get; set; }


        #region Help Message Attached Properties

        #region ShowHelpEvent Attached property
        public static RoutedEvent GetShowHelpEvent(DependencyObject obj)
        {
            return (RoutedEvent)obj.GetValue(ShowHelpEventProperty);
        }

        public static void SetShowHelpEvent(DependencyObject obj, RoutedEvent value)
        {
            obj.SetValue(ShowHelpEventProperty, value);
        }

        public static readonly DependencyProperty ShowHelpEventProperty = DependencyProperty.RegisterAttached("ShowHelpEvent", typeof(RoutedEvent), typeof(ShellPanesService), new UIPropertyMetadata(FrameworkElement.GotFocusEvent, onShowHelpEventChanged));

        private static void onShowHelpEventChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            FrameworkElement fe = (FrameworkElement)obj;

            if (args.OldValue != null)
            {
                fe.RemoveHandler((RoutedEvent)args.OldValue, new RoutedEventHandler(ShowHelp));
            }

            fe.AddHandler((RoutedEvent)args.NewValue, new RoutedEventHandler(ShowHelp), false);
        }
        #endregion

        #region HideHelpEvent Attached property
        public static RoutedEvent GetHideHelpEvent(DependencyObject obj)
        {
            return (RoutedEvent)obj.GetValue(HideHelpEventProperty);
        }

        public static void SetHideHelpEvent(DependencyObject obj, RoutedEvent value)
        {
            obj.SetValue(HideHelpEventProperty, value);
        }

        public static readonly DependencyProperty HideHelpEventProperty = DependencyProperty.RegisterAttached("HideHelpEvent", typeof(RoutedEvent), typeof(ShellPanesService), new UIPropertyMetadata(FrameworkElement.LostFocusEvent, onHideHelpEventChanged));

        private static void onHideHelpEventChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            FrameworkElement fe = (FrameworkElement)obj;

            if (args.OldValue != null)
            {
                fe.RemoveHandler((RoutedEvent)args.OldValue, new RoutedEventHandler(HideHelp));
            }

            fe.AddHandler((RoutedEvent)args.NewValue, new RoutedEventHandler(HideHelp), false);
        }
        #endregion

        #region HelpMessage Attached property
        public static object GetHelpMessage(DependencyObject obj)
        {
            return (object)obj.GetValue(HelpMessageProperty);
        }

        public static void SetHelpMessage(DependencyObject obj, object value)
        {
            obj.SetValue(HelpMessageProperty, value);
        }

        public static readonly DependencyProperty HelpMessageProperty = DependencyProperty.RegisterAttached("HelpMessage", typeof(object), typeof(ShellPanesService), new UIPropertyMetadata(onHelpMessageChanged));

        private static void onHelpMessageChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            FrameworkElement fe = (FrameworkElement)obj;

            RoutedEvent displayEvent = GetShowHelpEvent(obj);
            RoutedEvent hideEvent = GetHideHelpEvent(obj);

            fe.RemoveHandler(displayEvent, new RoutedEventHandler(ShowHelp));
            fe.RemoveHandler(hideEvent, new RoutedEventHandler(HideHelp));

            fe.AddHandler(displayEvent, new RoutedEventHandler(ShowHelp), false);
            fe.AddHandler(hideEvent, new RoutedEventHandler(HideHelp), false);
        }
        #endregion

        #region RestoreLastHelpMessageOnHide Attached property

        public static bool GetRestoreLastHelpMessageOnHide(DependencyObject obj)
        {
            return (bool)obj.GetValue(RestoreLastHelpMessageOnHideProperty);
        }

        public static void SetRestoreLastHelpMessageOnHide(DependencyObject obj, bool value)
        {
            obj.SetValue(RestoreLastHelpMessageOnHideProperty, value);
        }

        public static readonly DependencyProperty RestoreLastHelpMessageOnHideProperty = DependencyProperty.RegisterAttached("RestoreLastHelpMessageOnHide", typeof(bool), typeof(ShellPanesService), new UIPropertyMetadata(false));

        #endregion

        #region Event handler

        private static void ShowHelp(object sender, RoutedEventArgs e)
        {
            try
            {
                DependencyObject objDO = (DependencyObject)sender;
                FrameworkElement objFE = sender as FrameworkElement;
                ContentControl helpPane = HelpPaneContentControl;

                if (helpPane == null)
                {
                    return;
                }

                bool restoreLastMessage = GetRestoreLastHelpMessageOnHide(objDO);
                object message = GetHelpMessage(objDO);

                if (restoreLastMessage)
                {
                    lastMessage = currentMessage;
                }
                else
                {
                    currentMessage = message;
                }

                if (helpPane != null)
                {
                    helpPane.Content = message;

                    if (objFE != null && objFE.DataContext != null)
                    {
                        helpPane.DataContext = objFE.DataContext;
                    }
                    else
                    {
                        helpPane.DataContext = objDO.GetValue(FrameworkElement.DataContextProperty);
                    }
                }
            }
            catch (Exception)
            {
                ((Control)sender).Background = new SolidColorBrush(Colors.Red);
            }
        }

        private static void HideHelp(object sender, RoutedEventArgs e)
        {
            try
            {
                DependencyObject obj = (DependencyObject)sender;
                ContentControl helpPane = HelpPaneContentControl;
                if (helpPane == null)
                {
                    return;
                }

                bool restoreLastMessage = GetRestoreLastHelpMessageOnHide(obj);

                if (helpPane != null)
                {
                    if (restoreLastMessage)
                    {
                        helpPane.Content = lastMessage;
                    }
                    else
                    {
                        currentMessage = null;
                        lastMessage = null;
                        helpPane.Content = null;
                        helpPane.DataContext = null;
                    }
                }
            }
            catch (Exception)
            {
                ((Control)sender).Background = new SolidColorBrush(Colors.Red);
            }
        }

        #endregion

        #endregion

        //#region Tasks Attached Properties
        //#region Attached property DisplayEvent
        //public static RoutedEvent GetDisplayTasksEvent(DependencyObject obj)
        //{
        //    return (RoutedEvent)obj.GetValue(DisplayTasksEventProperty);
        //}

        //public static void SetDisplayTasksEvent(DependencyObject obj, RoutedEvent value)
        //{
        //    obj.SetValue(DisplayTasksEventProperty, value);
        //}

        //// Using a DependencyProperty as the backing store for Display.  This enables animation, styling, binding, etc...
        //public static readonly DependencyProperty DisplayTasksEventProperty =
        //    DependencyProperty.RegisterAttached("DisplayTasksEvent", typeof(RoutedEvent), typeof(HotelUserControl), new FrameworkPropertyMetadata(FrameworkElement.GotFocusEvent, FrameworkPropertyMetadataOptions.None, OnTasksChangeDisplay));
        //#endregion

        //#region Attached property HideEvent

        //public static RoutedEvent GetHideTasksEvent(DependencyObject obj)
        //{
        //    return (RoutedEvent)obj.GetValue(HideTasksEventProperty);
        //}

        //public static void SetHideTasksEvent(DependencyObject obj, RoutedEvent value)
        //{
        //    obj.SetValue(HideTasksEventProperty, value);
        //}

        //// Using a DependencyProperty as the backing store for Hide.  This enables animation, styling, binding, etc...
        //public static readonly DependencyProperty HideTasksEventProperty =
        //    DependencyProperty.RegisterAttached("HideTasksEvent", typeof(RoutedEvent), typeof(HotelUserControl), new FrameworkPropertyMetadata(FrameworkElement.LostFocusEvent, FrameworkPropertyMetadataOptions.None, OnTasksChangeHide));

        //#endregion

        //#region Attached property Tasks
        //public static FrameworkElement GetTasks(DependencyObject obj)
        //{
        //    return (FrameworkElement)obj.GetValue(TasksProperty);
        //}

        //public static void SetTasks(DependencyObject obj, FrameworkElement value)
        //{
        //    obj.SetValue(TasksProperty, value);
        //}

        //// Using a DependencyProperty as the backing store for HelpMessage.  This enables animation, styling, binding, etc...
        //public static readonly DependencyProperty TasksProperty =
        //    DependencyProperty.RegisterAttached("Tasks", typeof(FrameworkElement), typeof(HotelUserControl), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.None, OnTasksChange));

        //#endregion

        //#region Event handler
        //static void OnTasksChangeDisplay(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        //{
        //    FrameworkElement fe = (FrameworkElement)obj;

        //    if (args.OldValue != null)
        //    {
        //        fe.RemoveHandler((RoutedEvent)args.OldValue, new RoutedEventHandler(DisplayTasks));
        //    }

        //    fe.AddHandler((RoutedEvent)args.NewValue, new RoutedEventHandler(DisplayTasks), false);
        //}

        //static void OnTasksChangeHide(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        //{
        //    FrameworkElement fe = (FrameworkElement)obj;

        //    if (args.OldValue != null)
        //    {
        //        fe.RemoveHandler((RoutedEvent)args.OldValue, new RoutedEventHandler(HideTasks));
        //    }

        //    fe.AddHandler((RoutedEvent)args.NewValue, new RoutedEventHandler(HideTasks), false);
        //}

        //static void OnTasksChange(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        //{
        //    FrameworkElement fe = (FrameworkElement)obj;
        //    RoutedEvent hideEvent = GetHideTasksEvent(obj);

        //    fe.RemoveHandler(hideEvent, new RoutedEventHandler(HideTasks));
        //    fe.AddHandler(hideEvent, new RoutedEventHandler(HideTasks), false);

        //    RoutedEvent displayEvent = GetDisplayTasksEvent(obj);

        //    fe.RemoveHandler(displayEvent, new RoutedEventHandler(DisplayTasks));
        //    fe.AddHandler(displayEvent, new RoutedEventHandler(DisplayTasks), false);
        //}

        //static void DisplayTasks(object sender, RoutedEventArgs e)
        //{
        //    DependencyObject obj = (DependencyObject)sender;
        //    ContentControl taskPane = MainWindow.TaskPaneContext;

        //    if (taskPane != null && Window.GetWindow(obj) == Window.GetWindow(taskPane))
        //    {
        //        FrameworkElement fe = GetTasks(obj);

        //        if (fe != null)
        //        {
        //            taskPane.Content = fe;
        //            fe.DataContext = GetDataContext(obj);
        //        }
        //    }
        //}

        //static void HideTasks(object sender, RoutedEventArgs e)
        //{
        //    DependencyObject obj = (DependencyObject)sender;
        //    ContentControl taskPane = MainWindow.TaskPaneContext;

        //    if (taskPane != null && Window.GetWindow(obj) == Window.GetWindow(taskPane))
        //    {
        //        FrameworkElement fe = GetTasks(obj);

        //        if (fe != null)
        //        {
        //            if (fe == taskPane.Content)
        //            {
        //                taskPane.Content = null;
        //            }
        //        }
        //        else
        //        {
        //            taskPane.Content = null;
        //        }
        //    }
        //}

        //#endregion
        //#endregion
    }
}
